/*
 * 描          述:  <描述>
 * 修  改   人:  Administrator
 * 修改时间:  2017年11月2日
 * <修改描述:>
 */
package com.tx.component.task.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tx.component.task.dao.TaskDetailDao;
import com.tx.component.task.model.TaskDetail;
import com.tx.component.task.service.TaskContextRegistry;
import com.tx.component.task.service.TaskDetailService;
import com.tx.core.exceptions.util.AssertUtils;
import com.tx.core.paged.model.PagedList;

/**
 * 任务详情业务层<br/>
 * <功能详细描述>
 * 
 * @author  Administrator
 * @version  [版本号, 2017年11月2日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class TaskDetailServiceImpl implements TaskDetailService {
    
    @SuppressWarnings("unused")
    private Logger logger = LoggerFactory
            .getLogger(TaskDetailServiceImpl.class);
    
    private TaskContextRegistry taskContextRegistry;
    
    private TaskDetailDao taskDetailDao;
    
    /** <默认构造函数> */
    public TaskDetailServiceImpl() {
        super();
    }
    
    /** <默认构造函数> */
    public TaskDetailServiceImpl(TaskDetailDao taskDetailDao,
            TaskContextRegistry taskContextRegistry) {
        super();
        this.taskDetailDao = taskDetailDao;
        this.taskContextRegistry = taskContextRegistry;
    }
    
    /**
     * @param id
     * @return
     */
    @Override
    public TaskDetail findById(String id) {
        AssertUtils.notEmpty(id, "id is empty.");
        
        TaskDetail condition = new TaskDetail();
        condition.setId(id);
        
        TaskDetail res = this.taskDetailDao.find(condition);
        this.taskContextRegistry.setIsModifyAble4Detail(Arrays.asList(res));
        
        return res;
    }
    
    /**
     * @param valid
     * @param params
     * @return
     */
    @Override
    public List<TaskDetail> queryList(Map<String, Object> params) {
        //生成查询条件
        params = params == null ? new HashMap<String, Object>() : params;
        
        //根据实际情况，填入排序字段等条件，根据是否需要排序，选择调用dao内方法
        List<TaskDetail> resList = this.taskDetailDao.queryList(params);
        this.taskContextRegistry.setIsModifyAble4Detail(resList);
        
        return resList;
    }
    
    /**
     * @param valid
     * @param params
     * @param pageIndex
     * @param pageSize
     * @return
     */
    @Override
    public PagedList<TaskDetail> queryPagedList(Map<String, Object> params,
            int pageIndex, int pageSize) {
        //生成查询条件
        params = params == null ? new HashMap<String, Object>() : params;
        
        //根据实际情况，填入排序字段等条件，根据是否需要排序，选择调用dao内方法
        PagedList<TaskDetail> resPagedList = this.taskDetailDao
                .queryPagedList(params, pageIndex, pageSize);
        this.taskContextRegistry
                .setIsModifyAble4Detail(resPagedList.getRecords());
        
        return resPagedList;
    }
    
    /**
     * @param valid
     * @param params
     * @return
     */
    @Override
    public int count(Map<String, Object> params) {
        //生成查询条件
        params = params == null ? new HashMap<String, Object>() : params;
        
        //根据实际情况，填入排序字段等条件，根据是否需要排序，选择调用dao内方法
        int res = this.taskDetailDao.count(params);
        
        return res;
    }
    
    /**
     * @param parentId
     * @param valid
     * @param params
     * @return
     */
    @Override
    public List<TaskDetail> queryChildrenByParentId(String parentId,
            Map<String, Object> params) {
        //判断条件合法性
        AssertUtils.notEmpty(parentId, "parentId is empty.");
        
        //生成查询条件
        params = params == null ? new HashMap<String, Object>() : params;
        params.put("parentId", parentId);
        
        //根据实际情况，填入排序字段等条件，根据是否需要排序，选择调用dao内方法
        List<TaskDetail> resList = this.taskDetailDao.queryList(params);
        this.taskContextRegistry.setIsModifyAble4Detail(resList);
        
        return resList;
    }
    
    /**
     * @param parentId
     * @param valid
     * @param params
     * @return
     */
    @Override
    public List<TaskDetail> queryDescendantsByParentId(String parentId,
            Map<String, Object> params) {
        //判断条件合法性
        AssertUtils.notEmpty(parentId, "parentId is empty.");
        
        //生成查询条件
        params = params == null ? new HashMap<String, Object>() : params;
        Set<String> ids = new HashSet<>();
        Set<String> parentIds = new HashSet<>();
        parentIds.add(parentId);
        
        List<TaskDetail> resList = doNestedQueryChildren(ids,
                parentIds,
                params);
        this.taskContextRegistry.setIsModifyAble4Detail(resList);
        
        return resList;
    }
    
    /**
     * 查询嵌套列表<br/>
     * <功能详细描述>
     * @param ids
     * @param parentIds
     * @param params
     * @return [参数说明]
     * 
     * @return List<TaskDetail> [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    private List<TaskDetail> doNestedQueryChildren(Set<String> ids,
            Set<String> parentIds, Map<String, Object> params) {
        if (CollectionUtils.isEmpty(parentIds)) {
            return new ArrayList<TaskDetail>();
        }
        
        //ids避免数据出错时导致无限循环
        Map<String, Object> queryParams = new HashMap<>();
        queryParams.putAll(params);
        queryParams.put("parentIds", parentIds);
        List<TaskDetail> resList = queryList(queryParams);
        
        Set<String> newParentIds = new HashSet<>();
        for (TaskDetail bdTemp : resList) {
            if (!ids.contains(bdTemp.getId())) {
                newParentIds.add(bdTemp.getId());
            }
            ids.add(bdTemp.getId());
        }
        //嵌套查询下一层级
        resList.addAll(doNestedQueryChildren(ids, newParentIds, params));
        return resList;
    }
    
}
